package com.bleeth.fx.parser;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import com.bleeth.fx.helper.ControlsHelper;
import com.bleeth.fx.layout.FormBuilder;
import com.bleeth.fx.layout.GirdCell;
import javafx.geometry.Pos;
import javafx.scene.layout.Region;

import java.util.HashMap;
import java.util.Map;

/**
 * @author ：Bleeth
 * @date ：2021-11-12
 * @description：
 */
public class MetaParser {

    private static final Map<String, String> refJsonMap = new HashMap<>();
    private static final Map<String, Region> refRegionMap = new HashMap<>();


    public static Region parse(String jsonStr) {
        JSONObject root = new JSONObject(jsonStr);
        String formId = root.getStr("formId");
        double formHeight = root.getDouble("formHeight");
        double formWidth = root.getDouble("formWidth");
        String formPos = root.getStr("formPos");

        JSONArray formArray = root.getJSONArray("form");

        FormBuilder builder = FormBuilder.form(formWidth, formHeight, convertFormPos(formPos));

        for (int rowIndex = 0; rowIndex < formArray.size(); rowIndex++) {
            JSONObject rowObject = formArray.getJSONObject(rowIndex);
            String rowType = rowObject.getStr("rowType");
            Boolean debug = rowObject.getBool("debug",false);
            Double rowSpacing = rowObject.getDouble("rowSpacing", 0D);
            Boolean rowCover = rowObject.getBool("rowCover",false);
            Double rowHeight = rowObject.getDouble("rowHeight", 0D);
            JSONArray rowArray = rowObject.getJSONArray("row");
            if (StrUtil.equalsIgnoreCase(rowType, "EMPTY")) {
                builder.addEmptyRow(rowHeight);
                continue;
            }
            if (StrUtil.equalsIgnoreCase(rowType, "NORMAL")) {
                GirdCell[] girdCells = new GirdCell[rowArray.size()];
                for (int cellIndex = 0; cellIndex < rowArray.size(); cellIndex++) {
                    JSONObject cellObj = rowArray.getJSONObject(cellIndex);
                    Integer cellSpan = cellObj.getInt("cellSpan");
                    Double cellWidth = cellObj.getDouble("cellWidth", 0D);
                    String cellPos = cellObj.getStr("cellPos");
                    Double cellSpacing = cellObj.getDouble("cellSpacing", 0D);
                    String cellColor = cellObj.getStr("cellColor");
                    if (cellSpan != null && cellSpan != 0) {
                        GirdCell cell = GirdCell.createCell(cellSpan, convertCellPos(cellPos), cellSpacing, cellColor);
                        girdCells[cellIndex] = cell;
                    } else {
                        GirdCell cell = GirdCell.createCell(cellWidth, convertCellPos(cellPos), cellSpacing, cellColor);
                        girdCells[cellIndex] = cell;
                    }
                }
                FormBuilder.RowBuilder rowBuilder = null;
                if (rowCover != null && rowCover) {
                    rowBuilder = builder.coverRow(girdCells);
                } else {
                    rowBuilder = builder.addRow(girdCells);
                }

                for (int cellIndex = 0; cellIndex < rowArray.size(); cellIndex++) {
                    JSONObject cellObj = rowArray.getJSONObject(cellIndex);
                    Double scale = cellObj.getDouble("cellScale",0D);
                    String cellCover = cellObj.getStr("cellCover");
                    JSONArray cellArray = cellObj.getJSONArray("cell");
                    if (cellArray == null) {
                        continue;
                    }
                    for (int regionIndex = 0; regionIndex < cellArray.size(); regionIndex++) {
                        JSONObject regionObj = cellArray.getJSONObject(regionIndex);
                        String refId = regionObj.getStr("refId");
                        String regionId = regionObj.getStr("regionId");
                        String regionType = regionObj.getStr("regionType");
                        JSONObject controlsObj = regionObj.getJSONObject("region");
                        if (StrUtil.isNotEmpty(refId)) {
                            Region region = queryRegion(refId);
                            if (StrUtil.equalsIgnoreCase(cellCover,"TRUE")) {
                                rowBuilder.coverCell(cellIndex, region, scale, regionId);
                            } else {
                                rowBuilder.addCell(cellIndex, region,scale, regionId);
                            }
                            continue;
                        }

                        Region region = parseControls(controlsObj, regionType);
                        if (StrUtil.equalsIgnoreCase(cellCover,"TRUE")) {
                            rowBuilder.coverCell(cellIndex, region, scale,refId);
                        } else {
                            rowBuilder.addCell(cellIndex, region, scale, refId);
                        }
                    }
                }
                rowBuilder.endRow(debug, rowSpacing);
            }
        }

        return builder.build("", formId);
    }


    public static Pos convertFormPos(String formPos) {
        if (StrUtil.isEmpty(formPos)) {
            return null;
        }
        return Pos.valueOf(formPos);
    }

    public static Pos convertCellPos(String cellPos) {
        if (StrUtil.isEmpty(cellPos)) {
            return null;
        }
        return Pos.valueOf(cellPos);
    }

    public static Region queryRegion(String refId) {
        Region region = refRegionMap.get(refId);
        if (region == null) {
            String jsonStr = refJsonMap.get(refId);
            return parse(jsonStr);
        }
        return refRegionMap.get(refId);
    }

    private static Region parseControls(JSONObject controlsObj, String regionType) {
        if (StrUtil.equalsIgnoreCase(regionType, "BUTTON")) {
            String text = controlsObj.getStr("text");
            String btnClass = controlsObj.getStr("btnClass");
            String textClass = controlsObj.getStr("textClass");
            return ControlsHelper.createBtn(text, btnClass, textClass);
        }
        if (StrUtil.equalsIgnoreCase(regionType, "LABEL")) {
            String text = controlsObj.getStr("text");
            String btnClass = controlsObj.getStr("btnClass");
            String textClass = controlsObj.getStr("textClass");
            return ControlsHelper.createLabel(text, btnClass, textClass);
        }
        if (StrUtil.equalsIgnoreCase(regionType, "TEXT_FIELD")) {
            String text = controlsObj.getStr("text");
            String tipText = controlsObj.getStr("tipText");
            String btnClass = controlsObj.getStr("btnClass");
            String textClass = controlsObj.getStr("textClass");
            return ControlsHelper.createTextField(text, tipText,btnClass, textClass);
        }
        if (StrUtil.equalsIgnoreCase(regionType, "PASSWORD_FIELD")) {
            String text = controlsObj.getStr("text");
            String tipText = controlsObj.getStr("tipText");
            String btnClass = controlsObj.getStr("btnClass");
            String textClass = controlsObj.getStr("textClass");
            return ControlsHelper.createTextField(text, tipText,btnClass, textClass);
        }
        return new Region();
    }


}
